package com.aizuda.snailjob.template.datasource.handler;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import com.aizuda.snailjob.template.datasource.exception.SnailJobDatasourceException;
import com.aizuda.snailjob.template.datasource.persistence.po.CreateDt;
import com.aizuda.snailjob.template.datasource.persistence.po.CreateUpdateDt;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;

/**
 * @author: dhb52 (adopted from ruoyi-vue-plus)
 * @date: 2024-06-16 23:22
 */
@Slf4j
public class InjectionMetaObjectHandler implements MetaObjectHandler {

    private static final Boolean isGaussDriver = isGaussDriver();

    /**
     * GaussDB 和 PostgreSQL 推荐使用 java.sql.Timestamp
     */
    private static LocalDateTime convert(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return Timestamp.valueOf(dateTime).toLocalDateTime();
    }

    /**
     * 判断是否为 GaussDB 驱动（gsjdbc4 / postgres 等）
     */
    private static boolean isGaussDriver() {
        try {
            String driver = java.sql.DriverManager.getDrivers().nextElement().getClass().getName().toLowerCase();
            boolean isGaussDriver = driver.contains("gauss") || driver.contains("postgres");
            log.info("==========isGaussDriver: {}", isGaussDriver);
            return isGaussDriver;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public void insertFill(MetaObject metaObject) {
        try {
            if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof CreateDt baseEntity) {
                LocalDateTime current = ObjectUtil.isNotNull(baseEntity.getCreateDt())
                    ? baseEntity.getCreateDt() : LocalDateTime.now();
                baseEntity.setCreateDt(isGaussDriver ? convert(current) : current);
            }
            if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof CreateUpdateDt baseEntity) {
                LocalDateTime current = ObjectUtil.isNotNull(baseEntity.getCreateDt())
                    ? baseEntity.getCreateDt() : LocalDateTime.now();
                baseEntity.setUpdateDt(isGaussDriver ? convert(current) : current);
            }
        } catch (Exception e) {
            throw new SnailJobDatasourceException(" Automatic injection exception =>" + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        try {
            if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof CreateUpdateDt baseEntity) {
                LocalDateTime current = LocalDateTime.now();
                // 更新时间填充(不管为不为空)
                baseEntity.setUpdateDt(isGaussDriver ? convert(current) : current);
            }
        } catch (Exception e) {
            throw new SnailJobDatasourceException(" Automatic injection exception =>" + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
        }
    }

}
